#ifndef __M1VDEC_INTERNAL_H__
#define __M1VDEC_INTERNAL_H__

#include <string.h>

#include "m1vdec_config.h"
#include "../lwmpeg/lwmpeg.h"

#define __STDC__ 1
#define NOCONTROLS 1
//#define M1VDEC_FLOAT_DCT 1

typedef int Sint32;
typedef short Sint16;
typedef char Sint8;
typedef unsigned int Uint32;
typedef unsigned short Uint16;
typedef unsigned char Uint8;

typedef double TimeStamp;

struct LWMPEG_MPEGstream
{
	virtual int copy_data(void *destBytes, unsigned int requested) = 0;
	virtual void peek_bytes(void *destBytes, unsigned int requested) = 0;
	virtual bool eof() = 0;
};

struct LWMPEG_MPEGvideo
{
	Uint32 _w;
	Uint32 _h;
	Uint32 _ow;
	Uint32 _oh;
	struct LWMPEG_vid_stream *_stream;
	double _fps;
	const char *_error;
	int _target_bpp;
	bool _fatalError;

	LWMPEG_MPEGstream *mpeg;
	double play_time;

	LWMPEG_Allocator _alloc;

	LWMPEG_MPEGvideo(LWMPEG_MPEGstream *stream, int target_bpp, const LWMPEG_Allocator *alloc);
	~LWMPEG_MPEGvideo();

	void ExecuteDisplay(struct LWMPEG_vid_stream *vid_stream, double current_time);
	void DisplayFrame( struct LWMPEG_vid_stream * vid_stream );
	bool DecodeFrame();
	void SetFrameSkip( int frames );

	bool _imgAvailable;
	Uint8 *_imgY;
	Uint8 *_imgU;
	Uint8 *_imgV;
	Uint32 _frameRateNum;
	Uint32 _frameRateDenom;

	inline double Time()
	{
		return play_time;
	}

	inline void SetError(const char *err)
	{
		_error = err;
	}

	inline bool GetImage(unsigned int *frameRateNumerator, unsigned int *frameRateDenominator, unsigned int *width, unsigned int *height,
		unsigned int *lpitch, unsigned int *cpitch, const unsigned char **yPlane, const unsigned char **uPlane, const unsigned char **vPlane)
	{
		if(!_imgAvailable)
			return false;

		if(width) *width = _ow;
		if(height) *height = _oh;
		if(lpitch) *lpitch = _w;
		if(cpitch) *cpitch = _w/2;
		if(yPlane) *yPlane = _imgY;
		if(uPlane) *uPlane = _imgU;
		if(vPlane) *vPlane = _imgV;

		_imgAvailable = false;

		return true;
	}
};

inline Uint32 SDL_SwapBE32(Uint32 i)
{
	union
	{
		Uint8 b[4];
		Uint32 i;
	} u;

	u.b[0] = static_cast<Uint8>(i >> 24);
	u.b[1] = static_cast<Uint8>(i >> 16);
	u.b[2] = static_cast<Uint8>(i >> 8);
	u.b[3] = static_cast<Uint8>(i);
	return u.i;
}

#define M1VDEC_BUFFER_SIZE 20000

#endif
